home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / kcl.lha / c / unixfsys.c < prev    next >
C/C++ Source or Header  |  1987-06-04  |  12KB  |  644 lines

  1. /*
  2. (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
  3. Copying of this file is authorized to users who have executed the true and
  4. proper "License Agreement for Kyoto Common LISP" with SIGLISP.
  5. */
  6.  
  7. #include "include.h"
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <pwd.h>
  11.  
  12.  
  13. #define    MAXPATHLEN    1024
  14.  
  15. object Kwild;
  16.  
  17.  
  18. #ifdef ATT
  19. #include <sys/dir.h>
  20. #include <mnttab.h>
  21.  
  22. char dotdot[3*16+2] = "../../../../../../../../../../../../../../../../.";
  23.  
  24. static char *getwd_buf;
  25. static int getwd_bufp;
  26.  
  27. char *
  28. getwd(buffer)
  29. char *buffer;
  30. {
  31.     getwd_buf = buffer;
  32.     getwd1(0);
  33.     if (getwd_bufp == 0)
  34.         getwd_buf[getwd_bufp++] = '/';
  35.     getwd_buf[getwd_bufp] = '\0';
  36.     return(getwd_buf);
  37. }
  38.  
  39. getwd1(n)
  40. int n;
  41. {
  42.     struct stat st, dev_st;
  43.     struct direct dir;
  44.     ino_t ino;
  45.     struct mnttab mnt;
  46.     FILE *fp;
  47.     register int i;
  48.     char buf[BUFSIZ];
  49.     static char dev_name[64];
  50.  
  51.     if (stat(dotdot+(16-n)*3, &st) < 0)
  52.         FEerror("Can't get the current working directory.", 0);
  53.     ino = st.st_ino;
  54.     if (ino == 2)
  55.         goto ROOT;
  56.     getwd1(n+1);
  57.     fp = fopen(dotdot+(16-n-1)*3, "r");
  58.     if (fp == NULL)
  59.         FEerror("Can't get the current working directory.", 0);
  60.     setbuf(fp, buf);
  61.     fread(&dir, sizeof(struct direct), 1, fp);
  62.     fread(&dir, sizeof(struct direct), 1, fp);
  63.     for (;;) {
  64.         if (fread(&dir, sizeof(struct direct), 1, fp) <= 0)
  65.             break;
  66.         if (dir.d_ino == ino)
  67.             goto FOUND;
  68.     }
  69.     fclose(fp);
  70.     FEerror("Can't get the current working directory.", 0);
  71.  
  72. FOUND:
  73.     fclose(fp);
  74.     getwd_buf[getwd_bufp++] = '/';
  75.     for (i = 0;  i < DIRSIZ && dir.d_name[i] != '\0';  i++)
  76.         getwd_buf[getwd_bufp++] = dir.d_name[i];
  77.     return;
  78.  
  79. ROOT:
  80.     fp = fopen("/etc/mnttab", "r");
  81.     if (fp == NULL)
  82.         FEerror("Can't get the current working directory.", 0);
  83.     setbuf(fp, buf);
  84.     for (;;) {
  85.         if (fread(&mnt, sizeof(struct mnttab), 1, fp) <= 0)
  86.             break;
  87.         if (mnt.mt_dev[0] != '/') {
  88.             strcpy(dev_name, "/dev/dsk/");
  89.             strcat(dev_name, mnt.mt_dev);
  90.             stat(dev_name, &dev_st);
  91.         } else
  92.             stat(mnt.mt_dev, &dev_st);
  93.         if (dev_st.st_rdev == st.st_dev)
  94.             goto DEV_FOUND;
  95.     }
  96.     fclose(fp);
  97.     getwd_bufp = 0;
  98.     return;
  99.  
  100. DEV_FOUND:
  101.     fclose(fp);
  102.     getwd_bufp = 0;
  103.     for (i = 0;  mnt.mt_filsys[i] != '\0';  i++)
  104.         getwd_buf[i] = mnt.mt_filsys[i];
  105.     /* BUG FIX by Grant J. Munsey */
  106.     if (i == 1 && *getwd_buf == '/')
  107.         i = 0;    /* don't add an empty directory name */
  108.     /* END OF BUG FIX */
  109.     getwd_bufp = i;
  110. }
  111. #endif
  112.  
  113. #ifdef E15
  114. char *
  115. getwd(buffer)
  116. char *buffer;
  117. {
  118.     char *getcwd();
  119.  
  120.     return(getcwd(buffer, MAXPATHLEN));
  121. }
  122. #endif
  123.  
  124. #ifdef DGUX
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. #endif
  177.  
  178.  
  179. coerce_to_filename(pathname, p)
  180. object pathname;
  181. char *p;
  182. {
  183.     int i;
  184.     object namestring;
  185.  
  186.     namestring = coerce_to_namestring(pathname);
  187.     if (namestring->st.st_fillp >= MAXPATHLEN - 16) {
  188.         vs_push(namestring);
  189.         FEerror("Too long filename: ~S.", 1, namestring);
  190.     }
  191.     for (i = 0;  i < namestring->st.st_fillp;  i++)
  192.         p[i] = namestring->st.st_self[i];
  193.     p[i] = '\0';
  194. }
  195.  
  196. object
  197. truename(pathname)
  198. object pathname;
  199. {
  200.     register char *p, *q;
  201.     char filename[MAXPATHLEN];
  202.     char truefilename[MAXPATHLEN];
  203.     char current_directory[MAXPATHLEN];
  204.     char directory[MAXPATHLEN];
  205.     char *getwd();
  206.  
  207.     coerce_to_filename(pathname, filename);
  208.     for (p = filename, q = 0;  *p != '\0';  p++)
  209.         if (*p == '/')
  210.             q = p;
  211.     if (q == filename) {
  212.         q++;
  213.         getwd(current_directory);
  214.         p = "/";
  215.     } else if (q == 0) {
  216.         q = filename;
  217.         p = getwd(current_directory);
  218.     } else {
  219.         *q++ = '\0';
  220.         getwd(current_directory);
  221.         if (chdir(filename) < 0)
  222.             FEerror("Cannot get the truename of ~S.", 1, pathname);
  223.         p = getwd(directory);
  224.     }
  225.     if (p[0] == '/' && p[1] == '\0') {
  226.         if (strcmp(q, "..") == 0)
  227.             strcpy(truefilename, "/.");
  228.         else
  229.             sprintf(truefilename, "/%s", q);
  230.     } else if (strcmp(q, ".") == 0)
  231.         strcpy(truefilename, p);
  232.     else if (strcmp(q, "..") == 0) {
  233.         for (q = p + strlen(p);  *--q != '/';) ;
  234.         if (p == q)
  235.             strcpy(truefilename, "/.");
  236.         else {
  237.             *q = '\0';
  238.             strcpy(truefilename, p);
  239.             *q = '/';
  240.         }
  241.     } else
  242.         sprintf(truefilename, "%s/%s", p, q);
  243.     chdir(current_directory);
  244.     vs_push(make_simple_string(truefilename));
  245.     pathname = coerce_to_pathname(vs_head);
  246.     vs_pop;
  247.     return(pathname);
  248. }
  249.  
  250. bool
  251. file_exists(file)
  252. object file;
  253. {
  254.     char filename[MAXPATHLEN];
  255.     struct stat filestatus;
  256.  
  257.     coerce_to_filename(file, filename);
  258.     if (stat(filename, &filestatus) >= 0)
  259.         return(TRUE);
  260.     else
  261.         return(FALSE);
  262. }
  263.  
  264. FILE *
  265. backup_fopen(filename, option)
  266. {
  267.     char backupfilename[MAXPATHLEN];
  268.     char command[MAXPATHLEN * 2];
  269.  
  270.     strcat(strcpy(backupfilename, filename), ".BAK");
  271.     sprintf(command, "mv %s %s", filename, backupfilename);
  272.     system(command);
  273.     return(fopen(filename, option));
  274. }
  275.  
  276. int
  277. file_len(fp)
  278. FILE *fp;
  279. {
  280.     struct stat filestatus;
  281.  
  282.     fstat(fileno(fp), &filestatus);
  283.     return(filestatus.st_size);
  284. }
  285.  
  286. Ltruename()
  287. {
  288.     check_arg(1);
  289.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  290.     vs_base[0] = truename(vs_base[0]);
  291. }
  292.  
  293. Lrename_file()
  294. {
  295.     char filename[MAXPATHLEN];
  296.     char newfilename[MAXPATHLEN];
  297.     char command[MAXPATHLEN * 2];
  298.  
  299.     check_arg(2);
  300.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  301.     check_type_or_Pathname_string_symbol(&vs_base[1]);
  302.     coerce_to_filename(vs_base[0], filename);
  303.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  304.     vs_base[1] = coerce_to_pathname(vs_base[1]);
  305.     vs_base[1] = merge_pathnames(vs_base[1], vs_base[0], Cnil);
  306.     coerce_to_filename(vs_base[1], newfilename);
  307.     sprintf(command, "mv %s %s", filename, newfilename);
  308.     system(command);
  309.     vs_push(vs_base[1]);
  310.     vs_push(truename(vs_base[0]));
  311.     vs_push(truename(vs_base[1]));
  312.     vs_base += 2;
  313. }
  314.  
  315. Ldelete_file()
  316. {
  317.     char filename[MAXPATHLEN];
  318.  
  319.     check_arg(1);
  320.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  321.     coerce_to_filename(vs_base[0], filename);
  322.     if (unlink(filename) < 0)
  323.         FEerror("Cannot delete the file ~S.", 1, vs_base[0]);
  324.     vs_base[0] = Ct;
  325. }
  326.  
  327. Lprobe_file()
  328. {
  329.     check_arg(1);
  330.  
  331.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  332.     if (file_exists(vs_base[0]))
  333.         vs_base[0] = truename(vs_base[0]);
  334.     else
  335.         vs_base[0] = Cnil;
  336. }
  337.  
  338. Lfile_write_date()
  339. {
  340.     char filename[MAXPATHLEN];
  341.     struct stat filestatus;
  342.  
  343.     check_arg(1);
  344.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  345.     coerce_to_filename(vs_base[0], filename);
  346.     if (stat(filename, &filestatus) < 0)
  347.         FEerror("Cannot get the file status of ~S.", 1, vs_base[0]);
  348.     vs_base[0] = unix_time_to_universal_time(filestatus.st_mtime);
  349. }
  350.  
  351. Lfile_author()
  352. {
  353.     char filename[MAXPATHLEN];
  354.     struct stat filestatus;
  355.     struct passwd *pwent;
  356.     extern struct passwd *getpwuid();
  357.  
  358.     check_arg(1);
  359.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  360.     coerce_to_filename(vs_base[0], filename);
  361.     if (stat(filename, &filestatus) < 0)
  362.         FEerror("Cannot get the file status of ~S.", 1, vs_base[0]);
  363.     pwent = getpwuid(filestatus.st_uid);
  364.     vs_base[0] = make_simple_string(pwent->pw_name);
  365. }
  366.  
  367. Luser_homedir_pathname()
  368. {
  369.     struct passwd *pwent;
  370.     char filename[MAXPATHLEN];
  371.     register int i;
  372.     extern struct passwd *getpwuid();
  373.  
  374.     if (vs_top - vs_base > 1)
  375.         too_many_arguments();
  376.     pwent = getpwuid(getuid());
  377.     strcpy(filename, pwent->pw_dir);
  378.     i = strlen(filename);
  379.     if (filename[i-1] != '/') {
  380.         filename[i++] = '/';
  381.         filename[i] = '\0';
  382.     }
  383.     vs_base[0] = make_simple_string(filename);
  384.     vs_top = vs_base+1;
  385.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  386. }
  387.  
  388.  
  389. #ifdef BSD
  390. Ldirectory()
  391. {
  392.     char filename[MAXPATHLEN];
  393.     char command[MAXPATHLEN * 2];
  394.     FILE *fp;
  395.     register i, c;
  396.     object *top = vs_top;
  397.     char iobuffer[BUFSIZ];
  398.     extern FILE *popen();
  399.  
  400.     check_arg(1);
  401.  
  402.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  403.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  404.     if (vs_base[0]->pn.pn_name==Cnil && vs_base[0]->pn.pn_type==Cnil) {
  405.         coerce_to_filename(vs_base[0], filename);
  406.         strcat(filename, "*");
  407.     } else if (vs_base[0]->pn.pn_name==Cnil) {
  408.         vs_base[0]->pn.pn_name = Kwild;
  409.         coerce_to_filename(vs_base[0], filename);
  410.         vs_base[0]->pn.pn_name = Cnil;
  411.     } else if (vs_base[0]->pn.pn_type==Cnil) {
  412.         coerce_to_filename(vs_base[0], filename);
  413.         strcat(filename, "*");
  414.     } else
  415.         coerce_to_filename(vs_base[0], filename);
  416.     sprintf(command, "ls -d %s 2> /dev/null", filename);
  417.     fp = popen(command, "r");
  418.     setbuf(fp, iobuffer);
  419.     for (;;) {
  420.         for (i = 0;  c = getc(fp);  i++)
  421.             if (c <= 0)
  422.                 goto L;
  423.             else if (c == '\n')
  424.                 break;
  425.             else
  426.                 filename[i] = c;
  427.         filename[i] = '\0';
  428.         vs_push(make_simple_string(filename));
  429.         vs_head = truename(vs_head);
  430.     }
  431. L:
  432.     pclose(fp);
  433.     vs_push(Cnil);
  434.     while (vs_top > top + 1)
  435.         stack_cons();
  436.     vs_base = top;
  437. }
  438. #endif
  439.  
  440.  
  441. #ifdef ATT
  442. Ldirectory()
  443. {
  444.     object name, type;
  445.     char filename[MAXPATHLEN];
  446.     FILE *fp;
  447.     object *top = vs_top;
  448.     char iobuffer[BUFSIZ];
  449.     struct direct dir;
  450.     int i;
  451.  
  452.     check_arg(1);
  453.  
  454.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  455.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  456.     vs_push(vs_base[0]->pn.pn_name);
  457.     vs_push(vs_base[0]->pn.pn_type);
  458.     vs_base[0]->pn.pn_name = Cnil;
  459.     vs_base[0]->pn.pn_type = Cnil;
  460.     coerce_to_filename(vs_base[0], filename);
  461.     type = vs_base[0]->pn.pn_type = vs_pop;
  462.     name = vs_base[0]->pn.pn_name = vs_pop;
  463.     i = strlen(filename);
  464.     if (i > 1 && filename[i-1] == '/')
  465.         filename[i-1] = '\0';
  466.     if (i == 0)
  467.         strcpy(filename, ".");
  468.     fp = fopen(filename, "r");
  469.     if (fp == NULL) {
  470.         vs_push(make_simple_string(filename));
  471.         FEerror("Can't open the directory ~S.", 1, vs_head);
  472.     }
  473.     setbuf(fp, iobuffer);
  474.     fread(&dir, sizeof(struct direct), 1, fp);
  475.     fread(&dir, sizeof(struct direct), 1, fp);
  476.     filename[DIRSIZ] = '\0';
  477.     for (;;) {
  478.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  479.             break;
  480.         if (dir.d_ino == 0)
  481.             continue;
  482.         strncpy(filename, dir.d_name, DIRSIZ);
  483.         vs_push(make_simple_string(filename));
  484.         vs_head = coerce_to_pathname(vs_head);
  485.         if ((name == Cnil || name == Kwild ||
  486.              equal(name, vs_head->pn.pn_name)) &&
  487.             (type == Cnil || type == Kwild ||
  488.              equal(type, vs_head->pn.pn_type))) {
  489.             vs_head->pn.pn_directory
  490.             = vs_base[0]->pn.pn_directory;
  491.             vs_head = truename(vs_head);
  492.         } else
  493.             vs_pop;
  494.     }
  495.     fclose(fp);
  496.     vs_push(Cnil);
  497.     while (vs_top > top + 1)
  498.         stack_cons();
  499.     vs_base = top;
  500. }
  501. #endif
  502.  
  503.  
  504. #ifdef E15
  505. #include <sys/dir.h>
  506. Ldirectory()
  507. {
  508.     object name, type;
  509.     char filename[MAXPATHLEN];
  510.     FILE *fp;
  511.     object *top = vs_top;
  512.     char iobuffer[BUFSIZ];
  513.     struct direct dir;
  514.     int i;
  515.  
  516.     check_arg(1);
  517.  
  518.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  519.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  520.     vs_push(vs_base[0]->pn.pn_name);
  521.     vs_push(vs_base[0]->pn.pn_type);
  522.     vs_base[0]->pn.pn_name = Cnil;
  523.     vs_base[0]->pn.pn_type = Cnil;
  524.     coerce_to_filename(vs_base[0], filename);
  525.     type = vs_base[0]->pn.pn_type = vs_pop;
  526.     name = vs_base[0]->pn.pn_name = vs_pop;
  527.     i = strlen(filename);
  528.     if (i > 1 && filename[i-1] == '/')
  529.         filename[i-1] = '\0';
  530.     if (i == 0)
  531.         strcpy(filename, ".");
  532.     fp = fopen(filename, "r");
  533.     if (fp == NULL) {
  534.         vs_push(make_simple_string(filename));
  535.         FEerror("Can't open the directory ~S.", 1, vs_head);
  536.     }
  537.     setbuf(fp, iobuffer);
  538.     fread(&dir, sizeof(struct direct), 1, fp);
  539.     fread(&dir, sizeof(struct direct), 1, fp);
  540.     filename[DIRSIZ] = '\0';
  541.     for (;;) {
  542.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  543.             break;
  544.         if (dir.d_ino == 0)
  545.             continue;
  546.         strncpy(filename, dir.d_name, DIRSIZ);
  547.         vs_push(make_simple_string(filename));
  548.         vs_head = coerce_to_pathname(vs_head);
  549.         if ((name == Cnil || name == Kwild ||
  550.              equal(name, vs_head->pn.pn_name)) &&
  551.             (type == Cnil || type == Kwild ||
  552.              equal(type, vs_head->pn.pn_type))) {
  553.             vs_head->pn.pn_directory
  554.             = vs_base[0]->pn.pn_directory;
  555.             vs_head = truename(vs_head);
  556.         } else
  557.             vs_pop;
  558.     }
  559.     fclose(fp);
  560.     vs_push(Cnil);
  561.     while (vs_top > top + 1)
  562.         stack_cons();
  563.     vs_base = top;
  564. }
  565. #endif
  566.  
  567.  
  568. #ifdef DGUX
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617. #endif
  618.  
  619. siLchdir()
  620. {
  621.     char filename[MAXPATHLEN];
  622.  
  623.     check_arg(1);
  624.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  625.     coerce_to_filename(vs_base[0], filename);
  626.     if (chdir(filename) < 0)
  627.         FEerror("Can't change the current directory to ~S.",
  628.             1, vs_base[0]);
  629. }
  630.  
  631. init_unixfsys()
  632. {
  633.     make_function("TRUENAME", Ltruename);
  634.     make_function("RENAME-FILE", Lrename_file);
  635.     make_function("DELETE-FILE", Ldelete_file);
  636.     make_function("PROBE-FILE", Lprobe_file);
  637.     make_function("FILE-WRITE-DATE", Lfile_write_date);
  638.     make_function("FILE-AUTHOR", Lfile_author);
  639.     make_function("USER-HOMEDIR-PATHNAME", Luser_homedir_pathname);
  640.     make_function("DIRECTORY", Ldirectory);
  641.  
  642.     make_si_function("CHDIR", siLchdir);
  643. }
  644.